home *** CD-ROM | disk | FTP | other *** search
- /* File: Unknown.m - The 'Unknown' Application
- *
- * By: Christopher Lane
- * Symbolic Systems Resources Group
- * Knowledge Systems Laboratory
- * Stanford University
- *
- * Contributor(s):
- *
- * Jiro Nakamura (jiro@heights.cit.cornell.edu)
- *
- * Date: 2 April 1991
- *
- * Copyright: 1989, 1990 & 1991 by The Leland Stanford Junior University.
- * This program may be distributed without restriction for non-commercial use.
- */
-
- #import "Unknown.h"
-
- #import <c.h>
- #import <libc.h>
- #import <stdlib.h>
- #import <ldsyms.h>
- #import <strings.h>
-
- #import <sys/file.h>
- #import <sys/loader.h>
-
- #import <objc/typedstream.h>
- #import <objc/HashTable.h>
-
- #import <appkit/Panel.h>
- #import <appkit/Speaker.h>
- #import <appkit/Listener.h>
- #import <appkit/defaults.h>
-
- // #import <text/pathutil.h>
-
- #define APPLICATION "Unknown"
-
- #define VERIFYDEFAULTSTRING "Verify"
- #define DEFAULTVERIFYSTRING "Yes"
- #define REPORTERRORDEFAULTSTRING "ReportError"
- #define DEFAULTREPORTERRORSTRING "Yes"
-
- #define getDefaultValue(s) NXGetDefaultValue(APPLICATION, s)
- #define registerDefaults(s) NXRegisterDefaults(APPLICATION, s)
-
- #define getDefaultBoolValue(s) (BOOL) (strncmp(getDefaultValue(s), "Yes", 1) == EQ)
-
- static NXDefaultsVector UnknownDefaults = {
- { VERIFYDEFAULTSTRING, DEFAULTVERIFYSTRING },
- { REPORTERRORDEFAULTSTRING, DEFAULTREPORTERRORSTRING },
- { NULL }
- };
-
- #define HASHSEGMENT "__HASHTABLE"
- #define HASHSECTION "__DATA"
-
- #define ICONSEGMENT "__ICON"
- #define ICONSECTION "__header"
-
- #define BUFFERSIZE 1024
- #define BITSPERBYTE 8
-
- #define EXECUTESTRING "Execute?"
- #define ERRORSTRING "Error running '%s', exit code = %d."
-
- #define DEFAULTBUTTON "OK"
- #define ALTERNATEBUTTON "Cancel"
-
- typedef enum { LT = -1, EQ, GT } COMPARISON;
-
- char *basename(char *path)
- {
- char *s;
-
- if((s = rindex(path, '/')) != NULL) return ++s;
-
- return path;
- }
-
- char *parentname(char *path)
- {
- char *p, *s = NXCopyStringBuffer(path);
-
- if((p = rindex(s, '/')) == NULL) { p = s; *p++ = '.'; }
-
- *p = '\0';
-
- return s;
- }
-
- @implementation Unknown : Application
-
- + new
- {
- self = [super new];
-
- (void) registerDefaults(UnknownDefaults);
-
- return self;
- }
-
- - (BOOL) appAcceptsAnotherFile:sender { return(YES); };
-
- - (int) appOpenFile:(const char *) filename type:(const char *) aType
- {
- int status;
- char buffer[BUFFERSIZE];
- const char *program, *base = basename((char *) filename);
- HashTable *table = [self loadSegment:HASHSEGMENT section:HASHSECTION];
-
- if(access(filename, R_OK) == CERROR) return (int) [self unix_error:"access"];
- if(chdir(parentname((char *) filename)) == CERROR) return (int) [self unix_error:"chdir"];
-
- if((program = [table valueForKey:aType]) != NULL) {
- (void) sprintf(buffer, program, base, base, base, base, base);
- if(! getDefaultBoolValue(VERIFYDEFAULTSTRING) ||
- (NXRunAlertPanel(EXECUTESTRING, buffer, DEFAULTBUTTON, ALTERNATEBUTTON, NULL) == NX_OKTAG)) {
- if((status = system(buffer)) == CERROR) return (int) [self unix_error:"system"];
- status >>= BITSPERBYTE;
- if(status != EXIT_SUCCESS && getDefaultBoolValue(REPORTERRORDEFAULTSTRING))
- NXRunAlertPanel(NULL, ERRORSTRING, NULL, NULL, NULL, buffer, status);
- }
- }
- else return [self ReOpenFile:filename type:aType];
-
- return(YES);
- }
-
- - appDidInit:sender { return [self terminate:sender]; }
-
- - loadSegment:(const char *) segment section:(const char *) section
- {
- int size;
- id object;
- void *pointer;
- NXStream *stream;
- NXTypedStream *typedstream;
-
- pointer = getsectdata(segment, section, &size);
- stream = NXOpenMemory((const char *) pointer, size, NX_READONLY);
- typedstream = NXOpenTypedStream(stream, NX_READONLY);
- object = NXReadObject(typedstream);
- NXCloseTypedStream(typedstream);
-
- return object;
- }
-
- - (int) ReOpenFile:(const char *) filename type:(const char *) aType
- {
- int size, result;
- void *pointer;
- port_t port;
- id speaker = [NXApp appSpeaker];
- NXStream *stream;
- char application[BUFFERSIZE], extension[BUFFERSIZE];
-
- pointer = getsectdata(ICONSEGMENT, ICONSECTION, &size);
- stream = NXOpenMemory((const char *) pointer, size, NX_READONLY);
-
- while(NXScanf(stream, "%*s %*s %s %s", application, extension) != EOF && strcmp(extension, aType) != 0);
-
- NXCloseMemory(stream, NX_FREEBUFFER);
-
- if(strcmp(application, [self appName]) == 0) return(YES);
-
- if((port = NXPortFromName(application, NULL)) == PORT_NULL)
- return (int) [self unix_error:"NXPortFromName"];
-
- [speaker setSendPort:port];
-
- if([speaker openFile:filename ok:&result] != SEND_SUCCESS)
- return (int) [self unix_error:"openFile:ok:"];
-
- return(YES);
- }
-
- - (BOOL) unix_error:(const char *) string
- {
- perror(string);
- return(NO);
- }
-
- @end
-